﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ZenBridge.Properties;
using ZenBridge.ZfApi;

namespace ZenBridge
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        static private ZenfolioLoginDialog _loginDialog;
        static private ZenfolioClient _client = new ZenfolioClient();
        static private System.Collections.Generic.Queue<FileInfo> _uploadQueue = new System.Collections.Generic.Queue<FileInfo>();

        /// <summary>
        /// Zero-parameter constructor
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Convenience function to write a message to the User Console
        /// </summary>
        /// <param name="message"></param>
        public void NotifyConsole(String message)
        {
            textBoxConsole.AppendText(message + "\n");
            textBoxConsole.ScrollToEnd();
            labelStatus.Content = message.Replace("\n", " ");
        }

        /// <summary>
        /// Adds a file to the upload queue.
        /// </summary>
        /// <param name="fileToQueue">The file to add to the queue</param>
        public void QueueUpload(string fileToQueue)
        {
            FileInfo file = new FileInfo(fileToQueue);
            _uploadQueue.Enqueue(file);
            NotifyConsole("Added:\n " + file.Name);
            //listViewUploadQueue.ItemsSource = _uploadQueue;
            listViewUploadQueue.Items.Add(file);
        }

        /// <summary>
        /// Disables the buttons that require Zenfolio authentication.
        /// </summary>
        private void DisableZenfolioButtons()
        {
            buttonCreateGallery.IsEnabled = false;
            buttonUpload.IsEnabled = false;
        }

        /// <summary>
        /// Enables the buttons that require Zenfolio authentication.
        /// </summary>
        private void EnableZenfolioButtons()
        {
            buttonCreateGallery.IsEnabled = true;
            buttonUpload.IsEnabled = true;
        }
        
        /// <summary>
        /// Event handler called when the window has finished loading. When the
        /// app is first instantiated, pulls in the initial set of command-line
        /// arguments, and the adds them to the upload queue.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.DataContext = _client;
            _client.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_client_PropertyChanged);
            _client.NotifyUser += new EventHandler<NotifyUserEventArgs>(_client_NotifyUser);
            _client.PhotoUploadComplete += new EventHandler<PhotoUploadCompleteEventArgs>(_client_PhotoUploadComplete);
            _client.PhotoUploadProgressChanged += new EventHandler<PhotoUploadProgressChangedEventArgs>(_client_PhotoUploadProgressChanged);
            
            (App.Current as ZenBridge.App).NewFileQueued += new EventHandler(MainWindow_NewFileQueued);

            if (Settings.Default.PicasaButtonInstalled)
            {
                buttonInstallPicasaButton.Content = "Re-Install Picasa Button...";
            }

            NotifyConsole("ZenBridge starting.");
        }

        void _client_PhotoUploadProgressChanged(object sender, PhotoUploadProgressChangedEventArgs e)
        {
            progressBarUpload.Value += e.BytesDone;
        }

        void _client_PhotoUploadComplete(object sender, PhotoUploadCompleteEventArgs e)
        {
            listViewUploadQueue.Items.Remove(e.FileInfo);
            progressBarUpload.Maximum -= e.FileInfo.Length;
            progressBarUpload.Value -= e.FileInfo.Length;
        }

        void _client_NotifyUser(object sender, NotifyUserEventArgs e)
        {
            NotifyConsole(e.Message);
            textBoxConsole.ScrollToEnd();
        }

        void _client_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Group")
            {
                treeViewGalleries.ItemsSource = _client.Group.Elements;
            }

        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Settings.Default.Save();
        }

        private void MainWindow_NewFileQueued(object sender, EventArgs e)
        {
            try
            {
                while (ZenBridge.App.CommandLineArgsQueue.Count > 0)
                {
                    QueueUpload(ZenBridge.App.CommandLineArgsQueue.Dequeue());
                }
            }
            catch (Exception exception)
            {
                NotifyConsole(exception.Message);
            }
        }

        private void buttonZfLogin_Click(object sender, RoutedEventArgs e)
        {
            if (_client.IsAuth)
            {
                _client.Logout();
                DisableZenfolioButtons();
                NotifyConsole("user logged out.");
                buttonZfLogin.Content = "Zenfolio Login...";
            }
            else
            {
                _loginDialog = new ZenfolioLoginDialog();
                _loginDialog.Owner = this;
                _loginDialog.ShowDialog();

                if (_loginDialog.DialogResult == true)
                {
                    NotifyConsole("Logging in...");
                    Mouse.OverrideCursor = Cursors.Wait;
                    try
                    {
                        if (_client.Login(_loginDialog.Username, _loginDialog.Password.ToString()))
                        {
                            NotifyConsole("user: " + _loginDialog.Username + " successfully logged in.");
                            buttonZfLogin.Content = "Zenfolio Logout";
                            EnableZenfolioButtons();

                            _client.LoadUserGroups();
                        }
                        else
                        {
                            NotifyConsole("login failed.");
                        }
                    }
                    catch (Exception exception)
                    {
                        NotifyConsole(exception.Message);
                    }
                    finally
                    {
                        Mouse.OverrideCursor = Cursors.Arrow;
                    }
                }
            }
        }

        private void buttonUpload_Click(object sender, RoutedEventArgs e)
        {
            if (_uploadQueue.Count == 0)
            {
                NotifyConsole("Upload queue is empty.");
            }
            
            try
            {
                while (_uploadQueue.Count > 0)
                {
                    NotifyConsole("Beginning upload of " + _uploadQueue.Peek().Name);
                    _client.UploadUserPhoto(_uploadQueue.Peek(), treeViewGalleries.SelectedItem as PhotoSet);
                    progressBarUpload.Maximum += _uploadQueue.Dequeue().Length;
                }
            }
            catch (Exception exception)
            {
                NotifyConsole(exception.Message);
            }
        }

        private void buttonInstallPicasaButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ZenBridgeIntegrate.InstallPicasaButton();
                buttonInstallPicasaButton.Content = "Re-Install Picasa Button...";
                Settings.Default.PicasaButtonInstalled = true;
            }
            catch (Exception exception)
            {
                NotifyConsole(exception.Message);
            }
        }

        private void textBoxConsole_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            textBoxConsole.SelectAll();
        }

        private void treeViewGalleries_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if ( (e.NewValue != null) &&
                 (e.NewValue.GetType() == typeof(PhotoSet)) &&
                 ((e.NewValue as PhotoSet).Type == PhotoSetType.Gallery))
            {
                menuItemGallery.Header = ((GroupElement)treeViewGalleries.SelectedValue).Title;
            }
            else
            {
                menuItemGallery.Header = "Select Gallery";
            }
        }

        private void listViewUploadQueue_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                BitmapImage source = new BitmapImage(new Uri(
                    (listViewUploadQueue.SelectedItem as FileInfo).FullName, UriKind.Absolute)
                );
                imageCurrent.Source = source;
            }
            catch (Exception exception)
            {
                imageCurrent.Source = null;
                NotifyConsole(exception.Message);
            }
        }

    }

}
